package com.chao.deeply.forkjoin;

import java.util.concurrent.ExecutionException;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.ForkJoinTask;
import java.util.concurrent.RecursiveTask;

/**
 * @author : Rookie
 * @description :
 * @date : 2023/5/13
 */
public class ForkJoinDemo {

    public static void main(String[] args) throws ExecutionException, InterruptedException {
        ForkJoinPool forkJoinPool = new ForkJoinPool();
        long startTime = System.currentTimeMillis();
        ForkJoinTask<Long> task = forkJoinPool.submit(new MyForkJoinTask(0L, 10_0000_0000L));
        Long res = task.get();
        System.out.println("最终结果为 " + res + "花费时间 " + (System.currentTimeMillis() - startTime) + " 毫秒");
    }

    public static class MyForkJoinTask extends RecursiveTask<Long> {
        // 每个任务的任务量
        private static final Integer MAX = 5000;
        // 子任务开始计算的值
        private Long startValue;
        // 子任务结束计算的值
        private Long endValue;

        public MyForkJoinTask(Long startValue, Long endValue) {
            this.startValue = startValue;
            this.endValue = endValue;
        }

        @Override
        protected Long compute() {
            //（2）求解，当子问题划分得足够小时，用较简单的方法解决；
            if (endValue - startValue < MAX) {
//                System.out.println(Thread.currentThread().getName()+": 开始计算的部分：startValue = " + startValue + ";endValue = " + endValue);
                long totalValue = 0L;
                for (long index = this.startValue; index <= this.endValue; index++) {
                    totalValue += index;
                }
                return totalValue;
            }
            //（1）分解，将要解决的问题划分成若干规模较小的同类问题；
            else {
                MyForkJoinTask subTask1 = new MyForkJoinTask(startValue, (startValue + endValue) / 2);
                subTask1.fork();
                MyForkJoinTask subTask2 = new MyForkJoinTask((startValue + endValue) / 2 + 1, endValue);
                subTask2.fork();
                // （3）合并，按原问题的要求，将子问题的解逐层合并构成原问题的解。
                return subTask1.join() + subTask2.join();
            }
        }
    }
}
